import java.rmi.RemoteException;
import java.util.Vector;

/*
 *  1. Reçoit les appels du serveur
 *  2. Mémorise l’état de l’objet partagé
 *     Id de l’objet, Mode de verrouillage (read/write),Le ou les sites clients (pour les rappeler ...)
 *  3. Il peut rappeler un site client (interface Client_itf)
 *  4. la gestion de la cohérence d’un objet est attribuée à une instance de la class ServerObject
 *  5. indique l’état de la cohérence de l’objet du point de vue du serveur, 
 *  	avec notamment le client écrivain si l’objet est en écriture ou la liste 
 *  	des clients lecteurs si l’objet est en lecture (afin d’être en mesure de
 *  	propager des invalidations) classe ServerObject. 
 *  6. Les appels au serveur sont transférés au ServerObject concerné.
 * */
public class ServerObject implements ServerObject_itf {
	
	private int id;
   // L'etat du ServerObject --l'object partager est ecrit : lockType = WL
	private int lockType;
	private Client_itf writer;
	private Vector<Client_itf> readers;
	// reference d'object partager
	private Object obj;

	public ServerObject(int id, Object obj) throws RemoteException {
		this.id = id;
		this.lockType = EtatLock.NL;
		this.obj = obj;
		this.writer = null;
		this.readers = new Vector<Client_itf>();
	}

	public ServerObject() {
		super();
	}

	public Object lock_read(Client_itf c) {
		/*
		 * Dans ce méthode, on ne doit pas reflechir le cas dans
		 * SlidesProjetObjDup.pdf à page 20 parce que le Client n'appelle pas ce
		 * méthode.
		 */
		switch (this.lockType) {
		// Le cas dans SlidesProjetObjDup.pdf à Page 17,
		case EtatLock.NL:
			this.lockType = EtatLock.RL;
			if (!this.readers.contains(c))
				this.readers.add(c);
			break;
		// Le cas dans SlidesProjetObjDup.pdf à Page 16,18,
		case EtatLock.RL:
			if (!this.readers.contains(c))
				this.readers.add(c);
			break;
		// Le cas dans SlidesProjetObjDup.pdf à Page 19,21
		case EtatLock.WL:
			try {
				this.writer.reduce_lock(this.id);
				this.writer = null;
				if (!this.readers.contains(c))
					this.readers.add(c);
				break;
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		default:
			break;
		}
		return this.obj;
	}

	/**
	 * Appels locaux
	 */
	public Object lock_write(Client_itf c) {
		switch (this.lockType) {
		// Le cas dans SlidesProjetObjDup.pdf à Page 22,24
		// !!Comment traiter le cas à Page 25?
		case EtatLock.RL:
			this.lockType = EtatLock.WL;
			for (Client_itf reader : this.readers) {
				try {
					reader.invalidate_reader(this.id);
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
			this.writer = c;
			this.readers.removeAllElements();
			break;
		// Le cas dans SlidesProjetObjDup.pdf à Page 23
		case EtatLock.WL:
			try {
				this.writer.invalidate_writer(this.id);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			this.readers.removeAllElements();
			this.writer = c;
			break;
		}
		return obj;
	}
}
